package com.zzyl.nursing.service.impl;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.framework.web.service.TokenService;
import com.zzyl.nursing.dto.SelectDeviceDataListDto;
import com.zzyl.nursing.dto.UserLoginRequestDto;
import com.zzyl.nursing.vo.LoginVo;
import com.zzyl.nursing.vo.SelectDeviceDataListVo;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.FamilyMemberMapper;
import com.zzyl.nursing.domain.FamilyMember;
import com.zzyl.nursing.service.IFamilyMemberService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

/**
 * 老人家属Service业务层处理
 *
 * @author ruoyi
 * @date 2025-05-30
 */
@Service
public class FamilyMemberServiceImpl extends ServiceImpl<FamilyMemberMapper,FamilyMember> implements IFamilyMemberService
{
    @Autowired
    private FamilyMemberMapper familyMemberMapper;


    // 注入调用第三方接口的service

    @Autowired
    private WechatServiceImpl wechatService;


    // 注入生成 jwt 令牌的类
    @Autowired
   private TokenService tokenService;


    private static final String fillDataValue = "0";



    /**
     * 老人家属查询老人佩戴设备数据：按周查询
     *
     * @param dto // 查询参数
     * @return
     */
    @Override
    public List<SelectDeviceDataListVo> queryDeviceDataListByWeek(SelectDeviceDataListDto dto) {


        List<SelectDeviceDataListVo> dbResults = familyMemberMapper.queryDeviceDataListByWeek(dto);

        dbResults.forEach(item -> {
            //   把 时间转为只有天数
            String dateTime = item.getDateTime();
            item.setDateTime(getMonthAndDay(dateTime));

        });

        List<String> allDays = getInWeekDay(dto.getStartTime(), dto.getEndTime());

        List<SelectDeviceDataListVo> fullResults = new ArrayList<>();

        for (String day : allDays) {
            SelectDeviceDataListVo vo = new SelectDeviceDataListVo();
            // 给时间赋值
            vo.setDateTime(day);

            // 查找数据库中 是否有该时间数据，如果有就拿到第一个
            Optional<SelectDeviceDataListVo> dbMatch = dbResults.stream().filter(item -> item.getDateTime().equals(day)).findFirst();
            // 判断是否为空
            if (dbMatch.isPresent()) {
                vo.setDataValue(dbMatch.get().getDataValue());
            } else {
                vo.setDataValue(fillDataValue);
            }

            fullResults.add(vo);

        }

        return fullResults;
    }


    public List<String> getInWeekDay(String startTime, String endTime) {
        long startTimeStamp = Long.parseLong(startTime);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        LocalDate startDate = LocalDate.parse(sdf.format(new Date(startTimeStamp)));

        long endTimeStamp = Long.parseLong(endTime);
        SimpleDateFormat sdfEnd = new SimpleDateFormat("yyyy-MM-dd");
        LocalDate endDate = LocalDate.parse(sdfEnd.format(new Date(endTimeStamp)));

        List<LocalDate> dateList = new ArrayList<>();
        while (!startDate.isAfter(endDate)) {
            dateList.add(startDate);
            startDate = startDate.plusDays(1);
        }

        List<String> dateStrList = new ArrayList<>();
        dateList.forEach(item -> {
            dateStrList.add(getMonthAndDay(item.toString()));
        });

        return dateStrList;

    }

    public String getMonthAndDay(String dateTime) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate date = LocalDate.parse(dateTime, formatter);

        // 格式化时间
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM.dd");
        String format = date.format(dateTimeFormatter);
        return format;

    }


    /**
     * 老人家属查询老人佩戴设备数据
     *
     * @param dto // 查询参数
     * @return
     */
    @Override
    public List<SelectDeviceDataListVo> queryDeviceDataListByDay(SelectDeviceDataListDto dto) {

        List<SelectDeviceDataListVo> selectDeviceDataListVos = familyMemberMapper.queryDeviceDataListByDay(dto);
        selectDeviceDataListVos.forEach(item -> {
            //   把 时间转为只有小时
            String dateTime = item.getDateTime();
            item.setDateTime(getHour(dateTime));

        });


        List<SelectDeviceDataListVo> allDeviceDataListVos = new ArrayList<>();
        List<String> hoursList = generateFullHourList();
        // 给每个时间定义的初始值

        hoursList.forEach((itemHour) -> {
            // 创建1个map
            SelectDeviceDataListVo itemDataMap = new SelectDeviceDataListVo();
            itemDataMap.setDataValue(fillDataValue);
            itemDataMap.setDateTime(itemHour);
            allDeviceDataListVos.add(itemDataMap);
        });

        allDeviceDataListVos.forEach((allDeviceDataList) -> {
            selectDeviceDataListVos.forEach((itemDeviceDataListVo) -> {
                if (allDeviceDataList.getDateTime().equals(itemDeviceDataListVo.getDateTime())) {
                    allDeviceDataList.setDataValue(itemDeviceDataListVo.getDataValue());
                }
            });
        });

        return allDeviceDataListVos;
    }


    //  生成 0-23小时的列表
    public List<String> generateFullHourList() {
        List<String> hourList = new ArrayList<>();
        for (int i = 0; i <= 23; i++) {
            // 不为10 的 前面补0
            String hour = String.format("%02d", i) + ":00";
            hourList.add(hour);
        }
        return hourList;
    }

    public String getHour(String dateTime) {

        String[] hourList = dateTime.split(" ");
        if (hourList.length > 1) {
            return hourList[1];
        } else {
            return dateTime;
        }
    }

    /**
     * 查询老人家属
     *
     * @param id 老人家属主键
     * @return 老人家属
     */
    @Override
    public FamilyMember selectFamilyMemberById(Long id)
    {
        return getById(id);
    }

    /**
     * 查询老人家属列表
     *
     * @param familyMember 老人家属
     * @return 老人家属
     */
    @Override
    public List<FamilyMember> selectFamilyMemberList(FamilyMember familyMember)
    {
        return familyMemberMapper.selectFamilyMemberList(familyMember);
    }

    /**
     * 新增老人家属
     *
     * @param familyMember 老人家属
     * @return 结果
     */
    @Override
    public int insertFamilyMember(FamilyMember familyMember)
    {
        return save(familyMember)?1:0;
    }

    /**
     * 修改老人家属
     *
     * @param familyMember 老人家属
     * @return 结果
     */
    @Override
    public int updateFamilyMember(FamilyMember familyMember)
    {
        return updateById(familyMember)?1:0;
    }

    /**
     * 批量删除老人家属
     *
     * @param ids 需要删除的老人家属主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberByIds(Long[] ids)
    {
        return removeByIds(Arrays.asList(ids))?1:0;
    }

    /**
     * 删除老人家属信息
     *
     * @param id 老人家属主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberById(Long id)
    {
        return removeById(id)?1:0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LoginVo login(UserLoginRequestDto dto) {


        String code = dto.getCode(); // 临时登录的凭证code
        String phoneCode = dto.getPhoneCode();//  手机号编码
        String nickName = dto.getNickName(); // 微信昵称


        //  调用第三方 提供的接口  获取用户的openid，需要个参数是临时登录的code

        String openid = wechatService.getOpenid(code);

        // 根据openid  去我们老人表中查数据
        LambdaQueryWrapper<FamilyMember> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FamilyMember::getOpenId,openid);
        FamilyMember familyMember = familyMemberMapper.selectOne(queryWrapper);

        // 1.存手机号，存真的，所以要调用 微信提供的 获取手机号的接口，获取用户真正的手机号.需要个参数是前端传来的的code
        String phone = wechatService.getPhone(phoneCode);

        System.out.println("phone = " + phone);

        // 判断有没有查到
        if(familyMember==null){
        //   此时说明数据库中没有查到，要新建1个 存到表中
            // 向表里存数据，
            familyMember = new FamilyMember();
            familyMember.setPhone(phone);
            // 2. 给用户随机生成1个 名称+ 手机号的后4位
            //从DEFAULT_NICKNAME_PREFIX随机挑选一个 + 手机号的后四位 0-8
            // 随机取1个数
            String name = DEFAULT_NICKNAME_PREFIX.get(new Random().nextInt(DEFAULT_NICKNAME_PREFIX.size()));
            //  手机号后4位
            String phoneLastFour = phone.substring(7);
            //  昵称
            String newName = name + phoneLastFour;
            familyMember.setName(newName);


            familyMember.setOpenId(openid);

        //     把数据存到表中、
            familyMemberMapper.insert(familyMember);
        //     此时会有 1个问题，就是 mybatis-plus 中的新增有 自动填充功能，自动填充 涉及到loginUserid,
        //     但是 小程序中没有这些字段，所以我们要修改以下mybatis-plus中 自动填充的功能


        } else {
        //      还有一种可能就是 在 表中查到了，但是用户是可能更改手机号的，
            //      所以我们要拿到从 腾讯 微信返回的手机号 和我们库中存的手机号，比较，不一样就把腾讯返回的存到我们表中
        if(!StrUtil.equals(familyMember.getPhone(),phone)){
            familyMember.setPhone(phone);
        //     调用更新接口，更新我们数据库中的数据
        }
        familyMemberMapper.updateById(familyMember);
        }


        // 存完数据了，要 构建jwt 令牌 返回给 前端 ：jwt 令牌 用 若依 提供的 TokenService 这个类
        // 但是这个类中 创建jwt  和 解析jwt 令牌的方法 createToken 和parseToken 都是私有的，所以 要改为 public 公共的
        Map<String,Object> mapToken = new HashMap<>();

        // 要把用户的id 和昵称 存到jwt 中，因为用户id 后面要用，

        mapToken.put("id",familyMember.getId());
        mapToken.put("nickName",familyMember.getName());

        String token = tokenService.createToken(mapToken);

        // 生成vo,把信息存到vo中
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        loginVo.setNickName(familyMember.getName());
        return loginVo;

    }

    static List<String> DEFAULT_NICKNAME_PREFIX = ListUtil.of("生活更美好",
            "大桔大利",
            "日富一日",
            "好柿开花",
            "柿柿如意",
            "一椰暴富",
            "大柚所为",
            "杨梅吐气",
            "天生荔枝"
    );

}
